Skip to content

All interpolating functions write data as calculated and don't avoid negs#20972

Merged
TurboGit merged 2 commits intodarktable-org:masterfrom
jenshannoschwalm:interpolators_dont_clipnegs
May 9, 2026
Merged

All interpolating functions write data as calculated and don't avoid negs#20972
TurboGit merged 2 commits intodarktable-org:masterfrom
jenshannoschwalm:interpolators_dont_clipnegs

Conversation

@jenshannoschwalm
Copy link
Copy Markdown
Collaborator

Until now the interpolating scalers (used in demosaic and finalscale) and all interpolating modules (ashift, lens, liquify ...) calculated data and made sure output is at least zero.

We did that to avoid undershoots in very dark regions for example by the lanczos variants.

This leads to a few subtle problems:

  • we might have valid negative data in some colorspaces so clipping negatives is not desired.
  • if a module does not scale but only crops (happening in demosaic or finalscale) the negative data are copied for further processing.
  • we likely will not clip all channel symmetrically so possibly subtle color casts happen in dark areas.

So - make all interpolators write to output as calculated.

…negatives

Until now the interpolating scalers (used in demosaic and finalscale) and all interpolating modules
(ashift, lens, liquify ...) calculated data and made sure output is at least zero.

We did that to avoid undershoots in very dark regions for example by the lanczos variants.

This leads to a few subtle problems:
- we might have valid negative data in some colorspaces so clipping negatives is not desired.
- if a module does not scale but only crops (happening in demosaic or finalscale) the negative
  data are copied for further processing.
- we likely will not clip all channel symmetrically so possibly subtle color casts happen in
  dark areas.

So - make all interpolators write to output as calculated.
@jenshannoschwalm jenshannoschwalm added this to the 5.6 milestone May 9, 2026
@jenshannoschwalm jenshannoschwalm added the scope: image processing correcting pixels label May 9, 2026
@jenshannoschwalm
Copy link
Copy Markdown
Collaborator Author

@TurboGit @kofa73 @ralfbrown @jandren @zisoft ... as you have worked on color maths :-)

Comments about testsuite diffs, all newly "failing" tests are commented,

HS AS EXPECTED should be understood as:
- we want it like this and CPU vs expected CPU diffs are ok
- we would want new expected images
HS AS MASTER should be understood as above but also failing on master log


BTW a few tests show les cpu vs expected diffs (those tests generated expected output
before we got the clip-negatives added).
------------------------------------------------------------------

HS AS EXPECTED Test 0018-perspective-corr
      Image mire1.cr2
      CPU & GPU version differ by 8695 pixels
      CPU vs. GPU report :
      ----------------------------------
      Max dE                   : 12.03953
      Avg dE                   : 0.00255
      Std dE                   : 0.05965
      ----------------------------------
      Pixels below avg + 0 std : 99.69 %
      Pixels below avg + 1 std : 99.69 %
      Pixels below avg + 3 std : 99.70 %
      Pixels below avg + 6 std : 99.73 %
      Pixels below avg + 9 std : 99.83 %
      ----------------------------------
      Pixels above tolerance   : 0.01 %
 
      Expected CPU vs. current CPU report :
      ----------------------------------
      Max dE                   : 2.65355
      Avg dE                   : 0.00261
      Std dE                   : 0.03880
      ----------------------------------
      Pixels below avg + 0 std : 99.46 %
      Pixels below avg + 1 std : 99.46 %
      Pixels below avg + 3 std : 99.47 %
      Pixels below avg + 6 std : 99.53 %
      Pixels below avg + 9 std : 99.60 %
      ----------------------------------
      Pixels above tolerance   : 0.00 %
 
  FAILS: image visually changed
         see diff.png for visual difference
         (15364 pixels changed)


HS AS EXPECTED Test 0036-liquify
      Image mire1.cr2
      CPU & GPU version differ by 645154 pixels
      CPU vs. GPU report :
      ----------------------------------
      Max dE                   : 8.11878
      Avg dE                   : 0.18529
      Std dE                   : 0.40559
      ----------------------------------
      Pixels below avg + 0 std : 77.09 %
      Pixels below avg + 1 std : 86.54 %
      Pixels below avg + 3 std : 97.79 %
      Pixels below avg + 6 std : 99.83 %
      Pixels below avg + 9 std : 99.98 %
      ----------------------------------
      Pixels above tolerance   : 0.31 %
 
      Expected CPU vs. current CPU report :
      ----------------------------------
      Max dE                   : 1.13791
      Avg dE                   : 0.00005
      Std dE                   : 0.00588
      ----------------------------------
      Pixels below avg + 0 std : 99.99 %
      Pixels below avg + 1 std : 99.99 %
      Pixels below avg + 3 std : 99.99 %
      Pixels below avg + 6 std : 99.99 %
      Pixels below avg + 9 std : 99.99 %
      ----------------------------------
      Pixels above tolerance   : 0.00 %


HS AS EXPECTED Test 0044-dithering-random
      Image mire1.cr2
      CPU & GPU version differ by 144 pixels
      CPU vs. GPU report :
      ----------------------------------
      Max dE                   : 2.20716
      Avg dE                   : 0.00003
      Std dE                   : 0.00533
      ----------------------------------
      Pixels below avg + 0 std : 99.99 %
      Pixels below avg + 1 std : 99.99 %
      Pixels below avg + 3 std : 99.99 %
      Pixels below avg + 6 std : 99.99 %
      Pixels below avg + 9 std : 99.99 %
      ----------------------------------
      Pixels above tolerance   : 0.00 %
 
      Expected CPU vs. current CPU report :
      ----------------------------------
      Max dE                   : 3.00262
      Avg dE                   : 0.00205
      Std dE                   : 0.03298
      ----------------------------------
      Pixels below avg + 0 std : 99.31 %
      Pixels below avg + 1 std : 99.31 %
      Pixels below avg + 3 std : 99.43 %
      Pixels below avg + 6 std : 99.63 %
      Pixels below avg + 9 std : 99.77 %
      ----------------------------------
      Pixels above tolerance   : 0.00 %
 
  FAILS: image visually changed
         see diff.png for visual difference
         (19287 pixels changed)

HS AS EXPECTED Test 0096-lensfun
      Image hlrecovery.arw
      CPU & GPU version differ by 197 pixels
      CPU & GPU large difference > 190
      CPU vs. GPU report :
      ----------------------------------
      Max dE                   : 1.11844
      Avg dE                   : 0.00004
      Std dE                   : 0.00501
      ----------------------------------
      Pixels below avg + 0 std : 99.99 %
      Pixels below avg + 1 std : 99.99 %
      Pixels below avg + 3 std : 99.99 %
      Pixels below avg + 6 std : 99.99 %
      Pixels below avg + 9 std : 99.99 %
      ----------------------------------
      Pixels above tolerance   : 0.00 %
 
      Expected CPU vs. current CPU report :
      ----------------------------------
      Max dE                   : 2.99275
      Avg dE                   : 0.02779
      Std dE                   : 0.13563
      ----------------------------------
      Pixels below avg + 0 std : 95.48 %
      Pixels below avg + 1 std : 95.50 %
      Pixels below avg + 3 std : 96.22 %
      Pixels below avg + 6 std : 99.28 %
      Pixels below avg + 9 std : 99.95 %
      ----------------------------------
      Pixels above tolerance   : 0.00 %
 
  FAILS: image visually changed
         see diff.png for visual difference
         (126734 pixels changed)

HS AS MASTER Test 0097-sigmoid
      Image mire1.cr2
      CPU & GPU version differ by 508 pixels
      CPU vs. GPU report :
      ----------------------------------
      Max dE                   : 0.94806
      Avg dE                   : 0.00009
      Std dE                   : 0.00679
      ----------------------------------
      Pixels below avg + 0 std : 99.98 %
      Pixels below avg + 1 std : 99.98 %
      Pixels below avg + 3 std : 99.98 %
      Pixels below avg + 6 std : 99.98 %
      Pixels below avg + 9 std : 99.98 %
      ----------------------------------
      Pixels above tolerance   : 0.00 %
 
      Expected CPU vs. current CPU report :
      ----------------------------------
      Max dE                   : 3.87786
      Avg dE                   : 0.05757
      Std dE                   : 0.17662
      ----------------------------------
      Pixels below avg + 0 std : 88.78 %
      Pixels below avg + 1 std : 89.50 %
      Pixels below avg + 3 std : 96.77 %
      Pixels below avg + 6 std : 99.81 %
      Pixels below avg + 9 std : 99.99 %
      ----------------------------------
      Pixels above tolerance   : 0.00 %
 
  FAILS: image visually changed
         see diff.png for visual difference
         (317588 pixels changed)

HS AS EXPECTED Test 0111-perspective-lanczos2
      Image mire1.cr2
      CPU & GPU version differ by 8724 pixels
      CPU vs. GPU report :
      ----------------------------------
      Max dE                   : 11.83769
      Avg dE                   : 0.00253
      Std dE                   : 0.05904
      ----------------------------------
      Pixels below avg + 0 std : 99.69 %
      Pixels below avg + 1 std : 99.69 %
      Pixels below avg + 3 std : 99.70 %
      Pixels below avg + 6 std : 99.72 %
      Pixels below avg + 9 std : 99.82 %
      ----------------------------------
      Pixels above tolerance   : 0.01 %
 
      Expected CPU vs. current CPU report :
      ----------------------------------
      Max dE                   : 2.65355
      Avg dE                   : 0.00261
      Std dE                   : 0.03886
      ----------------------------------
      Pixels below avg + 0 std : 99.46 %
      Pixels below avg + 1 std : 99.46 %
      Pixels below avg + 3 std : 99.48 %
      Pixels below avg + 6 std : 99.53 %
      Pixels below avg + 9 std : 99.60 %
      ----------------------------------
      Pixels above tolerance   : 0.00 %
 
  FAILS: image visually changed
         see diff.png for visual difference
         (15304 pixels changed)


HS AS EXPECTED Test 0112-perspective-lanczos3
      Image mire1.cr2
      CPU & GPU version differ by 8791 pixels
      CPU vs. GPU report :
      ----------------------------------
      Max dE                   : 11.67810
      Avg dE                   : 0.00252
      Std dE                   : 0.05835
      ----------------------------------
      Pixels below avg + 0 std : 99.69 %
      Pixels below avg + 1 std : 99.69 %
      Pixels below avg + 3 std : 99.69 %
      Pixels below avg + 6 std : 99.72 %
      Pixels below avg + 9 std : 99.82 %
      ----------------------------------
      Pixels above tolerance   : 0.01 %
 
      Expected CPU vs. current CPU report :
      ----------------------------------
      Max dE                   : 4.44373
      Avg dE                   : 0.00302
      Std dE                   : 0.04244
      ----------------------------------
      Pixels below avg + 0 std : 99.39 %
      Pixels below avg + 1 std : 99.39 %
      Pixels below avg + 3 std : 99.41 %
      Pixels below avg + 6 std : 99.48 %
      Pixels below avg + 9 std : 99.58 %
      ----------------------------------
      Pixels above tolerance   : 0.00 %
 
  FAILS: image visually changed
         see diff.png for visual difference
         (17269 pixels changed)

HS AS MASTER Test 0151-sigmoid-no-hue-preservation
      Image mire1.cr2
      CPU & GPU version differ by 527 pixels
      CPU vs. GPU report :
      ----------------------------------
      Max dE                   : 1.19925
      Avg dE                   : 0.00009
      Std dE                   : 0.00711
      ----------------------------------
      Pixels below avg + 0 std : 99.98 %
      Pixels below avg + 1 std : 99.98 %
      Pixels below avg + 3 std : 99.98 %
      Pixels below avg + 6 std : 99.98 %
      Pixels below avg + 9 std : 99.98 %
      ----------------------------------
      Pixels above tolerance   : 0.00 %
 
      Expected CPU vs. current CPU report :
      ----------------------------------
      Max dE                   : 3.87786
      Avg dE                   : 0.05788
      Std dE                   : 0.17690
      ----------------------------------
      Pixels below avg + 0 std : 88.70 %
      Pixels below avg + 1 std : 89.44 %
      Pixels below avg + 3 std : 96.77 %
      Pixels below avg + 6 std : 99.81 %
      Pixels below avg + 9 std : 99.99 %
      ----------------------------------
      Pixels above tolerance   : 0.00 %
 
  FAILS: image visually changed
         see diff.png for visual difference
         (319081 pixels changed)


HS AS EXPECTED Test 0161-overlay-modules-before-after
      Image mire1.cr2
      CPU & GPU version differ by 8563 pixels
      CPU vs. GPU report :
      ----------------------------------
      Max dE                   : 1.50401
      Avg dE                   : 0.00158
      Std dE                   : 0.02941
      ----------------------------------
      Pixels below avg + 0 std : 99.67 %
      Pixels below avg + 1 std : 99.67 %
      Pixels below avg + 3 std : 99.67 %
      Pixels below avg + 6 std : 99.69 %
      Pixels below avg + 9 std : 99.71 %
      ----------------------------------
      Pixels above tolerance   : 0.00 %
 
      Expected CPU vs. current CPU report :
      ----------------------------------
      Max dE                   : 2.96183
      Avg dE                   : 0.00040
      Std dE                   : 0.01718
      ----------------------------------
      Pixels below avg + 0 std : 99.93 %
      Pixels below avg + 1 std : 99.93 %
      Pixels below avg + 3 std : 99.93 %
      Pixels below avg + 6 std : 99.93 %
      Pixels below avg + 9 std : 99.93 %
      ----------------------------------
      Pixels above tolerance   : 0.00 %
 
  FAILS: image visually changed
         see diff.png for visual difference
         (1802 pixels changed)

HS AS EXPECTED Test 0166-haze-removal-v2
      Image mire1.cr2
      CPU & GPU version differ by 2475 pixels
      CPU vs. GPU report :
      ----------------------------------
      Max dE                   : 1.18699
      Avg dE                   : 0.00040
      Std dE                   : 0.01464
      ----------------------------------
      Pixels below avg + 0 std : 99.91 %
      Pixels below avg + 1 std : 99.91 %
      Pixels below avg + 3 std : 99.91 %
      Pixels below avg + 6 std : 99.91 %
      Pixels below avg + 9 std : 99.91 %
      ----------------------------------
      Pixels above tolerance   : 0.00 %
 
      Expected CPU vs. current CPU report :
      ----------------------------------
      Max dE                   : 22.40809
      Avg dE                   : 0.03764
      Std dE                   : 0.39179
      ----------------------------------
      Pixels below avg + 0 std : 97.15 %
      Pixels below avg + 1 std : 98.22 %
      Pixels below avg + 3 std : 99.18 %
      Pixels below avg + 6 std : 99.58 %
      Pixels below avg + 9 std : 99.75 %
      ----------------------------------
      Pixels above tolerance   : 0.44 %
 
  FAILS: image visually changed
         see diff.png for visual difference
         (79662 pixels changed)

HS AS EXPECTED Test 0173-capture-dual-markesteijn
      Image mire1-xtrans.raf
      CPU & GPU version differ by 2449 pixels
      CPU vs. GPU report :
      ----------------------------------
      Max dE                   : 1.85609
      Avg dE                   : 0.00043
      Std dE                   : 0.01565
      ----------------------------------
      Pixels below avg + 0 std : 99.91 %
      Pixels below avg + 1 std : 99.91 %
      Pixels below avg + 3 std : 99.91 %
      Pixels below avg + 6 std : 99.91 %
      Pixels below avg + 9 std : 99.91 %
      ----------------------------------
      Pixels above tolerance   : 0.00 %
 
      Expected CPU vs. current CPU report :
      ----------------------------------
      Max dE                   : 6.05529
      Avg dE                   : 0.00008
      Std dE                   : 0.01100
      ----------------------------------
      Pixels below avg + 0 std : 99.99 %
      Pixels below avg + 1 std : 99.99 %
      Pixels below avg + 3 std : 99.99 %
      Pixels below avg + 6 std : 99.99 %
      Pixels below avg + 9 std : 99.99 %
      ----------------------------------
      Pixels above tolerance   : 0.00 %
 
  FAILS: image visually changed
         see diff.png for visual difference
         (271 pixels changed)

HS AS EXPECTED Test 0175-agx
      Image mire1.cr2
      CPU & GPU version differ by 267 pixels
      CPU vs. GPU report :
      ----------------------------------
      Max dE                   : 1.14968
      Avg dE                   : 0.00005
      Std dE                   : 0.00536
      ----------------------------------
      Pixels below avg + 0 std : 99.99 %
      Pixels below avg + 1 std : 99.99 %
      Pixels below avg + 3 std : 99.99 %
      Pixels below avg + 6 std : 99.99 %
      Pixels below avg + 9 std : 99.99 %
      ----------------------------------
      Pixels above tolerance   : 0.00 %
 
      Expected CPU vs. current CPU report :
      ----------------------------------
      Max dE                   : 8.71797
      Avg dE                   : 0.00037
      Std dE                   : 0.02648
      ----------------------------------
      Pixels below avg + 0 std : 99.97 %
      Pixels below avg + 1 std : 99.97 %
      Pixels below avg + 3 std : 99.97 %
      Pixels below avg + 6 std : 99.97 %
      Pixels below avg + 9 std : 99.97 %
      ----------------------------------
      Pixels above tolerance   : 0.00 %
 
  FAILS: image visually changed
         see diff.png for visual difference
         (967 pixels changed)

HS AS EXPECTED Test 0176-color-harmonizer
      Image mire1.cr2
      CPU & GPU version differ by 1437 pixels
      CPU vs. GPU report :
      ----------------------------------
      Max dE                   : 4.84508
      Avg dE                   : 0.00038
      Std dE                   : 0.02072
      ----------------------------------
      Pixels below avg + 0 std : 99.95 %
      Pixels below avg + 1 std : 99.95 %
      Pixels below avg + 3 std : 99.95 %
      Pixels below avg + 6 std : 99.95 %
      Pixels below avg + 9 std : 99.95 %
      ----------------------------------
      Pixels above tolerance   : 0.00 %
 
      Expected CPU vs. current CPU report :
      ----------------------------------
      Max dE                   : 7.71922
      Avg dE                   : 0.00114
      Std dE                   : 0.03825
      ----------------------------------
      Pixels below avg + 0 std : 99.87 %
      Pixels below avg + 1 std : 99.87 %
      Pixels below avg + 3 std : 99.87 %
      Pixels below avg + 6 std : 99.87 %
      Pixels below avg + 9 std : 99.88 %
      ----------------------------------
      Pixels above tolerance   : 0.00 %
 
  FAILS: image visually changed
         see diff.png for visual difference
         (3601 pixels changed)

Comment thread src/common/math.h Outdated
@jenshannoschwalm
Copy link
Copy Markdown
Collaborator Author

Added a second commit

  • removing _interpolated_out()
  • fixed a remaining diff for graduated filter

@TurboGit two points remaining for me:

  1. would you prefer a squashed commit?
  2. There was an issue about quality/banding in graduated module. I could not see that in any relevant way while doing OpenCL and DEBINFO builds as we do for integration tests. I can see more of them in release builds, the reason seems to be the fast math variant. The problem is very low and is not visible in test suite but we have it. I checked performance here on my system and the difference is very small, with late gcc/libc i can't measure any diff so i would propose to use "HQ" variant for all builds for the sake of quality.

@TurboGit
Copy link
Copy Markdown
Member

TurboGit commented May 9, 2026

@jenshannoschwalm :

  1. In this case not the 2 commits are fine to me.
  2. I agree with your conclusion, if the diff is not measurable, let's unify the code.

1. As we don't clip for negatives in output any longer it's not used any longer.
2. Also fix clipping negatives in graduatednd CPU code and use std maths for all builds
   for the sake of quality (less banding).
@jenshannoschwalm jenshannoschwalm force-pushed the interpolators_dont_clipnegs branch from 0d8f02a to a04f253 Compare May 9, 2026 17:45
@jenshannoschwalm
Copy link
Copy Markdown
Collaborator Author

force pushed version with std maths for graduated as discussed.

Copy link
Copy Markdown
Member

@TurboGit TurboGit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@TurboGit TurboGit merged commit 142ecdb into darktable-org:master May 9, 2026
5 checks passed
@jenshannoschwalm jenshannoschwalm deleted the interpolators_dont_clipnegs branch May 10, 2026 03:49
@jandren
Copy link
Copy Markdown
Contributor

jandren commented May 10, 2026

This should be a improvement for noisy images if I understand the changes correctly.
The early clipping to positive only values disregarded half the noise distribution biasing the color of the final denosied output.

@jenshannoschwalm
Copy link
Copy Markdown
Collaborator Author

This should be a improvement for noisy images if I understand the changes correctly.

Yes - at least if we do the denoising before the demosaicer :-) Currently most clip negatives ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope: image processing correcting pixels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants